/**
 * @file         bsc_can_dispatch.h
 * @brief        CAN服务框架 ———— 分发类
 * @note    
 * @author       Jpz(puzhao.jin@hopechart.com, 靳普诏)
 * @data         2022-8-19
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2022-8-10   <td>1.0                   <td>Jpz             <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */

#ifndef _BSC_CAN_DISPATCH_H_
#define _BSC_CAN_DISPATCH_H_

#include "ofc/ofc_types.h"
#include "ofc/ofc_ring_buf.h"
#include "bsc_can_server/bsc_can_plug.h"


#ifdef __cplusplus
extern "C" {
#endif

typedef struct TBsCanDispatchTag TBsCanDispatch;
struct TBsCanDispatchTag
{
    TOfRingBuf ring_buf_;
    TBsCanPlug *plug_normal_;
    UInt8 channel_mask;         // 数据通道  （用户提供）. bit0 -> 4分别代表5个通道, bit位为1表示接收对应通道的数据
};

/**
 * 初始化分发对象
 * @param self      分发对象地址
 * @param buf       分发数据的缓存地址
 * @param buf_size  分发数据的缓存大小
 * @return >= 0 成功；
 *         <  0 失败
 */
Int32 TBsCanDispatchCreate(TBsCanDispatch *self, Byte *buf, Int32 buf_size);


/**
 * 反初始化分发对象
 * @param self      分发对象地址
 * @return
 */
void TBsCanDispatchDestroy(TBsCanDispatch *self);

/**
 * 调度一次插件，附属线程反复调用
 * @param self      分发对象地址
 * @return
 */
void TBsCanDispatchRunOnce(TBsCanDispatch *self);


/**
 * 设置数据通道.
 * @note bit0 -> 4分别代表5个通道, bit位为1表示接收对应通道的数据
 * @param self      分发对象地址
 * @return True 成功
 *         False 失败
 */
Bool TBsCanDispatchSetChannelMask(TBsCanDispatch *self, UInt8 channel_mask);

/**
 * 获取数据通道.
 * @param self      分发对象地址
 * @return 当前数据通道.
 */
UInt8 TBsCanDispatchChannelMask(TBsCanDispatch *self);


/**
 * 插件数量
 * @param self      分发对象地址
 * @return 插件数量
 */
Int32 TBsCanDispatchPlugCount(TBsCanDispatch *self);

/**
 * 注册插件列表
 * @param self          分发对象地址
 * @param plug_table    插件列表. 
 * @return 插件数量
 */
Int32 TBsCanDispatchRegisterPlugTable(TBsCanDispatch *self, TBsCanPlug *plug_table);

/**
 * 注销插件列表
 * @param self      分发对象地址
 * @return
 */
void TBsCanDispatchUnregisterPlugTable(TBsCanDispatch *self);


/**
 * 使能单独插件
 * @param plug_type     插件类别
 * @param plug_index    插件序号
 * @param enable       True:使能，False:关闭
 * @return >= 0 成功
 *         <  0 失败
 * @note:xxxxx
 */
Int32 TBsCanDispatchSetPlugEnable(TBsCanDispatch *self, UInt8 plug_index, Bool enable);

/**
 * 当前插件是否使能
 * @param plug_type     插件类别
 * @param plug_index    插件序号
 * @return True:使能，False:关闭
 * @note:xxxxx
 */
Bool TBsCanDispatchPlugEnabled(TBsCanDispatch *self, UInt8 plug_index);

/**
 * 获取当前插件的状态
 * @param plug_type     插件类别
 * @param plug_index    插件序号
 * @return  >= 0 插件状态 @ref TBsCanPlugState
 *          <  0 错误码
 * @note:xxxxx
 */
Int32 TBsCanDispatchPlugState(TBsCanDispatch *self, UInt8 plug_index);


/**
 * 主动读取分发对象buff中数据
 * @param *self                分发对象地址
 * @param *can_buf             数据缓存地址. 为NULL时返回当前可读数据帧数量
 * @param can_frame_count      读取数据帧个数. 单位:sizeof(TBsCanData)
 * @return 
 * @note 需要外部保证与 TBsCanDispatchRunOnce() 的多线程安全
 */
Int32 TBsCanDispatchRead(TBsCanDispatch *self, TBsCanData *can_buf, Int32 can_frame_count);


/**
 * 主动读取分发对象buff中数据(读取后读取点位置不变,而调用TOfRingBufRead后读取点位置后移)
 * @param *self                分发对象地址
 * @param *can_buf             数据缓存地址. 为NULL时返回当前可读数据帧数量
 * @param can_frame_count      读取数据帧个数. 单位:sizeof(TBsCanData)
 * @return 
 */
Int32 TBsCanDispatchPeek(TBsCanDispatch *self, TBsCanData *can_buf, Int32 can_frame_count);
    
    
/**
 * 从当前读取点开始,丢弃can_frame_size个数据帧(内部自动处理转弯)
 * @note 仅读取线程可以操作该函数
 * @param self: 对象实例
 * @param can_frame_count: 需要丢弃的数据帧个数; 
 * @return 无返回值
 * @note 需要外部保证与 TBsCanDispatchRunOnce() 的多线程安全
 */
void TBsCanDispatchPop(TBsCanDispatch *self, Int32 can_frame_count);

#ifdef __cplusplus
} // extern "C" {
#endif


#endif // #ifndef _BSC_CAN_DISPATCH_H_


